package com.polaris.live.ui.backpack.fragment

import android.animation.ObjectAnimator
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.StringUtils
import com.blankj.utilcode.util.TimeUtils
import com.polaris.live.R
import com.polaris.live.adapter.backpack.BackPackBubbleAdapter
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.constant.CommonConst
import com.polaris.live.common.ext.convertArabicDigitsToNormal
import com.polaris.live.common.mvvm.base2.BaseVbFragment
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.AppCodeUtils
import com.polaris.live.databinding.FragmentBubbleBinding
import com.polaris.live.dialog_fragment.room_background.fragment.OnBackgroundSelectCallback
import com.polaris.live.interface_bag.BackPackDataImpl
import com.polaris.live.interface_bag.BackPackSelectCallback
import com.polaris.live.resp.back_resp.UserBackpackDecorationResp
import com.polaris.live.translation.R.string
import com.polaris.live.utils.CommonUtils.toBoolean
import com.polaris.live.viewmodel.backpack.BackPackViewModel
import com.polaris.live.widget.AnimUtils
import com.polaris.live.widget.refresh.DressUpEmptyView

/**
 * BackpackFragment
 *
 * @author Created by 半仙 on 2024/1/31/031 17:43
 */
class BackpackFragment : BaseVbFragment<BackPackViewModel, FragmentBubbleBinding>(),
    BackPackDataImpl {

    private val mType: Long by lazy { arguments?.getLong("type") ?: 0L }

    //是否为派对房里的半弹窗
    private val mIsPopup by lazy { arguments?.getBoolean("isPopup") ?: false }

    private val mAdapter by lazy { BackPackBubbleAdapter() }

    private var mOnBackPackSelectCallback: BackPackSelectCallback? = null

    private var mIsShow = false

    private val mEmptyView by lazy { DressUpEmptyView(requireContext()) }

    private var mFirstVisiblePosition = 0
    private var mLastVisiblePosition = 0

    //使用回调，回调到外部告诉有效页取消选中
    private var mOnSelectCallback: OnBackgroundSelectCallback? = null
    fun setOnSelectCallback(l: OnBackgroundSelectCallback) {
        mOnSelectCallback = l
    }

    override fun initView(savedInstanceState: Bundle?) {
        mBinding.root.post {
            mEmptyView.layoutParams = ViewGroup.LayoutParams(mBinding.root.width, mBinding.root.height)
            mAdapter.setEmptyView(mEmptyView)
        }
        mBinding.recyclerView.layoutManager =
            if (mType == CommonConst.DressUp.USER_PROFILE || mType == CommonConst.DressUp.LIVE_EFFECT) {
                GridLayoutManager(requireContext(), 2)
            } else {
                GridLayoutManager(requireContext(), 3)
            }
        mBinding.recyclerView.adapter = mAdapter
        mBinding.recyclerView.itemAnimator = null
        mBinding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                mBinding.recyclerView.post {
                    checkVisibleItems()
                }
            }
        })

        mBinding.swipe.setOnRefreshListener {
            mViewModel.getBackpackByType(mType.toInt())
        }
        mBinding.swipe.setEnableLoadMore(false)
        initListener()
        initObserver()
    }

    private fun checkVisibleItems() {
        val layoutManager = mBinding.recyclerView.layoutManager as LinearLayoutManager
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
        val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()
        if (mFirstVisiblePosition != firstVisiblePosition || lastVisiblePosition != mLastVisiblePosition) {
            if (firstVisiblePosition > mFirstVisiblePosition) {
                for (i in mFirstVisiblePosition until firstVisiblePosition) {
                    mAdapter.notifyItemChanged(i, "hide")
                }
            }
            if (firstVisiblePosition < mFirstVisiblePosition) {
                for (i in firstVisiblePosition until mFirstVisiblePosition) {
                    mAdapter.notifyItemChanged(i, "show")
                }
            }
            if (lastVisiblePosition > mLastVisiblePosition) {
                for (i in mLastVisiblePosition + 1..lastVisiblePosition) {
                    mAdapter.notifyItemChanged(i, "show")
                }
            }
            if (lastVisiblePosition < mLastVisiblePosition) {
                for (i in lastVisiblePosition + 1..mLastVisiblePosition) {
                    mAdapter.notifyItemChanged(i, "hide")
                }
            }
            mFirstVisiblePosition = firstVisiblePosition
            mLastVisiblePosition = lastVisiblePosition

        }
    }

    fun getType(): Long {
        return mType
    }

    /**
     * 更新数据
     */
    fun updateData(type: Long) {
        if (!isCreated()) {
            return
        }
        if (mType == type) {
            mViewModel.getBackpackByType(mType.toInt())
        }

    }

    /**
     * 定时刷新
     */
    fun timerUpdate() {
        if (!isCreated()) {
            return
        }
        mBinding.recyclerView.post {
            // 收集需要删除的索引
            val indicesToRemove = mutableListOf<Int>()
            val nowServerTime = CacheUtil.getServerTime()
            mAdapter.data.forEachIndexed { index, item ->
                when {
                    item.expiredTime == null -> {} // 永久物品
                    item.expiredTime.toLong() - nowServerTime > 0 -> {
                        mAdapter.notifyItemChanged(index, "notify")
                    } // 未超时 刷新时间
                    else -> {
                        indicesToRemove.add(index)
                    }
                }
            }
            indicesToRemove.sortedDescending().forEach { index ->
                mAdapter.removeAt(index)
            }
        }
    }

    private fun initObserver() {
        mViewModel.mBackpackLiveData.observe(this) { resultState ->
            mBinding.swipe.finishRefresh()
            parseState(resultState, { resultData ->
                if (mType == CommonConst.DressUp.PARTY_BACKGROUND) {
                    val yesData = resultData.find { it.useStatus == AppConst.YESLONG }
                    val list = mutableListOf<UserBackpackDecorationResp>()
                    list.add(getDefUserBackpackDecorationResp(if (yesData == null) AppConst.YESLONG else AppConst.NOLONG))
                    list.addAll(resultData)
                    mAdapter.setList(list)
                } else {
                    mAdapter.setList(resultData)
                }

            })
        }

        mViewModel.mUseSuccessLiveData.observe(this) { resp ->
            if (resp.index != -1) {
                val item = mAdapter.data[resp.index]
                item.useStatus = resp.useStatus.toLong()
                if (item.decorationType == CommonConst.DressUp.PARTY_BACKGROUND) { //是派对背景
                    if (resp.useStatus.toLong() == AppConst.YESLONG) {
                        mAdapter.data.forEachIndexed { position, it ->
                            if (item.backpackId == it.backpackId && item.decorationId == it.decorationId) {
                                mAdapter.data[position] = item
                                mAdapter.notifyItemChanged(position)
                            } else {
                                it.useStatus = AppConst.NOLONG
                                mAdapter.notifyItemChanged(position)
                            }
                        }
                    } else {
                        mAdapter.data.forEachIndexed { position, it ->
                            if (it.backpackId == DEFUSERBACKPACKDECORATION) {
                                mAdapter.data[position].useStatus = AppConst.YESLONG
                                mAdapter.notifyItemChanged(position)
                            } else {
                                it.useStatus = AppConst.NOLONG
                                mAdapter.notifyItemChanged(position)
                            }
                        }
                    }
                    if (mIsPopup) {
                        mAdapter.setSelect(if (resp.useStatus.toBoolean()) resp.index else 0)
                        //通知自定义槽位页取消选中
                        mOnSelectCallback?.setOnSelectCallback(2)
                    }
                } else {
                    mAdapter.data.forEachIndexed { position, it ->
                        if (item.backpackId == it.backpackId && item.decorationId == it.decorationId) {
                            mAdapter.data[position] = item
                            mAdapter.notifyItemChanged(position)
                        } else {
                            if (item.useStatus.toBoolean()) {
                                it.useStatus = AppConst.NOLONG
                                mAdapter.notifyItemChanged(position)
                            }
                        }
                    }
                }
            }
        }
    }

    private fun initListener() {
        mEmptyView.setClickListener {
            mOnBackPackSelectCallback?.goShopping(mType)
        }
        mAdapter.setOnItemChildClickListener { _, view, position ->
            val item = mAdapter.data[position]
            when (view.id) {
                R.id.tv_chick -> {
                    if (item.backpackId == BackPackBubbleAdapter.NOT_HAVE) return@setOnItemChildClickListener
                    if (item.backpackId == DEFUSERBACKPACKDECORATION) { //默认背景
                        val index = mAdapter.data.indexOfFirst {
                            it.useStatus == AppConst.YESLONG && it.backpackId != DEFUSERBACKPACKDECORATION
                        }
                        if (index != -1) {
                            val data = mAdapter.data[index]
                            mViewModel.useDressUp(data.backpackId, AppConst.NO, data, index)
                        } else {
                            item.useStatus = AppConst.YESLONG
                            mAdapter.notifyItemChanged(position)
                            mOnSelectCallback?.setOnSelectCallback(2, true)
                        }
                    } else {
                        mViewModel.useDressUp(item.backpackId, AppConst.YES, item, position)
                    }

                    if (mIsShow && mAdapter.getLastSelect() == position) {
                        showDown()
                        mAdapter.setSelect(-1)
                        mOnBackPackSelectCallback?.onBackPackSelectCallback(null)
                        return@setOnItemChildClickListener
                    }
                    mAdapter.setSelect(position)
                    mOnBackPackSelectCallback?.onBackPackSelectCallback(item)
                    setDownData(item)
                    if (!mIsShow) {
                        showUp()
                    }
                }

                R.id.tv_chick1 -> {
                    if (item.backpackId == BackPackBubbleAdapter.NOT_HAVE) return@setOnItemChildClickListener
                    mViewModel.useDressUp(item.backpackId, AppConst.NO, item, position)
                }
            }
        }

        mAdapter.setOnItemClickListener { _, _, position ->
            val item = mAdapter.data.getOrNull(position) ?: return@setOnItemClickListener
            if (mIsPopup) {
                if (item.backpackId == BackPackBubbleAdapter.NOT_HAVE) return@setOnItemClickListener
                if (item.backpackId == DEFUSERBACKPACKDECORATION) { //默认背景
                    val index = mAdapter.data.indexOfFirst {
                        it.useStatus == AppConst.YESLONG && it.backpackId != DEFUSERBACKPACKDECORATION
                    }
                    if (index != -1) {
                        val data = mAdapter.data[index]
                        mViewModel.useDressUp(data.backpackId, AppConst.NO, data, index)
                    } else {
                        item.useStatus = AppConst.YESLONG
                        mAdapter.setSelect(position)
                        mAdapter.notifyItemChanged(position)
                        //通知自定义槽位页取消选中
                        mOnSelectCallback?.setOnSelectCallback(2, true)
                    }
                } else {
                    if (!item.useStatus.toBoolean()) {
                        mViewModel.useDressUp(item.backpackId, AppConst.YES, item, position)
                    }
                }
            } else {
                if (mIsShow && mAdapter.getLastSelect() == position) {
                    showDown()
                    mAdapter.setSelect(-1)
                    mOnBackPackSelectCallback?.onBackPackSelectCallback(null)
                    return@setOnItemClickListener
                }
                mAdapter.setSelect(position)
                mOnBackPackSelectCallback?.onBackPackSelectCallback(item)
                setDownData(item)
                if (!mIsShow) {
                    showUp()
                }
            }
        }
        showDown(0)
        mBinding.root.post {
            mBinding.nesScrollView.viewTreeObserver.addOnScrollChangedListener {
                if (mIsShow) {
                    showDown()
                }
            }
        }
    }

    private fun showUp() {
        mIsShow = true
        mBinding.tvContext.post {
            // 创建属性动画
            val translateYAnimator: ObjectAnimator =
                ObjectAnimator.ofFloat(
                    mBinding.consBottom,
                    "translationY",
                    mBinding.consBottom.height.toFloat(),
                    0f
                )
            translateYAnimator.interpolator = AccelerateDecelerateInterpolator()
            translateYAnimator.duration = 300 // 设置动画时长，单位毫秒
            // 启动动画
            AnimUtils.run(mBinding.consBottom, translateYAnimator)
        }
    }

    private fun setDownData(mUserBack: UserBackpackDecorationResp) {
        mBinding.tvContext.text = (mUserBack.sourceDescription ?: mUserBack.description) ?: ""
        if (mUserBack.backpackId == BackPackBubbleAdapter.NOT_HAVE) {
            mBinding.tvTime.text =
                StringUtils.getString(string.not_get_it)
        } else {
            mUserBack.createTime?.let {
                val millis2String =
                    TimeUtils.millis2String(it.toLong(), "yyyy-MM-dd").convertArabicDigitsToNormal()
                val showTime = if (AppCodeUtils.isAR()) {
                    "$millis2String${StringUtils.getString(string.get_it)}"
                } else {
                    "$millis2String${StringUtils.getString(string.get_it)}"
                }
                mBinding.tvTime.text = showTime
            }
        }
    }

    private fun showDown(durationTime: Long? = null) {
        mIsShow = false
        mBinding.tvContext.post {
            // 创建属性动画
            val translateYAnimator: ObjectAnimator =
                ObjectAnimator.ofFloat(
                    mBinding.consBottom,
                    "translationY",
                    0f,
                    mBinding.consBottom.height.toFloat()
                )
            translateYAnimator.interpolator = AccelerateDecelerateInterpolator()
            translateYAnimator.duration = if (durationTime == null) 300 else durationTime // 设置动画时长，单位毫秒
            // 启动动画
            AnimUtils.run(mBinding.consBottom, translateYAnimator)
        }
    }

    override fun onBackPackDataCallback(backPackList: List<UserBackpackDecorationResp>) {
        setonBackPackData(backPackList)

    }

    fun setonBackPackData(backPackList: List<UserBackpackDecorationResp>, isDefault: Boolean = true) {
        if (mType == CommonConst.DressUp.PARTY_BACKGROUND) {
            val indexOf = backPackList.indexOfFirst { it.useStatus.toBoolean() }
            val list = mutableListOf<UserBackpackDecorationResp>()
            list.add(getDefUserBackpackDecorationResp(if (indexOf == -1 && isDefault) AppConst.YESLONG else AppConst.NOLONG))
            list.addAll(backPackList)
            mAdapter.setList(list)
            //因为半弹窗会先把fragment初始化完所以直接隐藏展示就行
            //背包页是不会先初始化fragment的所以如果直接隐藏展示会崩溃
            if (mIsPopup) {
                mBinding.nesScrollView.visibility = View.VISIBLE
                mBinding.loadingView.visibility = View.GONE
                val selectIndex = list.indexOfFirst { it.useStatus.toBoolean() }
                mAdapter.setSelect(selectIndex)
            }
        } else {
            mAdapter.setList(backPackList)
        }
    }

    override fun onBackPackSelectCallback(position: Int) {
        if (mAdapter.getLastSelect() == position) return
        mAdapter.setSelect(position)
    }

    fun setOnBackPackSelectCallback(l: BackPackSelectCallback) {
        mOnBackPackSelectCallback = l
    }

    //在半弹窗的时候取消所有选中     给true的时候要选中默认背景
    fun setUncheckItem(needUnmount: Boolean) {
        if (!isCreated()) return
        val indexOf = mAdapter.data.indexOfFirst { it.useStatus.toBoolean() }
        val item2 = mAdapter.getItemOrNull(indexOf)
        item2?.useStatus = AppConst.NOLONG
        if (indexOf != -1) mAdapter.notifyItemChanged(indexOf)

        val item = mAdapter.getItemOrNull(mAdapter.getLastSelect()) ?: return
        item.useStatus = AppConst.NOLONG
        mAdapter.notifyItemChanged(mAdapter.getLastSelect())
        mAdapter.setSelect(-1)
        //背景选中默认的
        if (needUnmount) {
            val index = mAdapter.data.indexOfFirst { it.backpackId == DEFUSERBACKPACKDECORATION }
            if (index != -1) {
                val background = mAdapter.getItemOrNull(index) ?: return
                background.useStatus = AppConst.YESLONG
                mAdapter.setSelect(index)
                mAdapter.notifyItemChanged(index)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        mViewModel.putBackpackNew(1, mType)
        if (mAdapter.data.isEmpty()) {
            mOnBackPackSelectCallback?.onBackPackSelectCallback(null)
        }
        if (!mIsPopup) {
            mBinding.root.post {
                val index = mAdapter.getLastSelect()
                if (index == -1) {
                    val orNull = mAdapter.data.getOrNull(0) ?: return@post
                    mAdapter.setSelect(0)
                    mOnBackPackSelectCallback?.onBackPackSelectCallback(orNull)
                    setDownData(orNull)
                    if (!mIsShow) {
                        showUp()
                    }
                } else {
                    val orNull = mAdapter.data.getOrNull(index) ?: return@post
                    mOnBackPackSelectCallback?.onBackPackSelectCallback(orNull)
                    setDownData(orNull)
                    if (!mIsShow) {
                        showUp()
                    }
                }
            }
        }
    }

    /**
     * 获取一个默认背景
     */
    private fun getDefUserBackpackDecorationResp(useStatus: Long): UserBackpackDecorationResp {
        return UserBackpackDecorationResp(
            DEFUSERBACKPACKDECORATION,
            null,
            0L,
            CommonConst.DressUp.PARTY_BACKGROUND,
            "",
            "",
            StringUtils.getString(string.default_background),
            null,
            null,
            null,
            null,
            null,
            "",
            false,
            useStatus
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        mOnBackPackSelectCallback = null
    }

    companion object {

        const val DEFUSERBACKPACKDECORATION = -100L  //默认背景id
    }
}